import base64
import pickle
from django_redis import get_redis_connection


def merge_carts_cookies_redis(req, user, response):
    """
    合并购物车
    本项目需求 ：以cookie中的数据为准，以redis中的数据结构为准
    :return:
    """
    # 获取cookie中的购物车数据
    cart_str = req.COOKIES.get('carts')

    # 判断cookie中的购物车数据是否存在
    if not cart_str:
        # 如果不存在，不需要合并
        # return '暂不考虑'
        return response

    # 如果存在，合并
    # 字符串转字典
    cart_dict = get_cart_dict(cart_str)

    """
    1，redis取出的数据结构
    
    hash：一个user.id：
    {
        'sku_id1':'count',
        'sku_id2':'count'
    }
    
    set:
    {'sku_id', 'sku_id'}

    2，cookie中的数据结构
    {
        "sku_id1": {
            "count": "1",
            "selected": "True"
        },
        "sku_id3": {
            "count": "3",
            "selected": "True"
        }
    }
    """
    # 【重点】准备新的数据容器: 保存新的sku_id:count selected, unselected
    new_cart_dict = {}
    new_selected_add = []
    new_selected_rem = []

    # 遍历出cookie中的购物车数据,根据redis的数据结构，调整数据
    for sku_id, cookie_dict in cart_dict.items():
        # new_cart_dict[int(sku_id)] = cookie_dict['count']
        new_cart_dict[sku_id] = cookie_dict['count']

        if cookie_dict['selected']:
            new_selected_add.append(sku_id)
        else:
            new_selected_rem.append(sku_id)

    # 根据新的结构，进行合并到redis
    redis_conn = get_redis_connection('carts')
    pl = redis_conn.pipeline()
    """
    # redis中查询hash数据 {b'3':b'1', b'4':b'3'}
    redis_cart = redis_conn.hgetall('carts_%s' % user.id)
    # 查询set数据
    redis_selected = redis_conn.smembers('selected_%s' % user.id)
    """
    # 将从cookie获取的购物车数据写入到redis
    # pl.hset('carts_%s' % user.id, new_cart_dict)
    pl.hmset('carts_%s' % user.id, new_cart_dict)  # 一次写入多条数据

    print(new_selected_add)
    print(*new_selected_add)
    # 如果存在勾选的商品
    if new_selected_add:
        pl.sadd('selected_%s' % user.id, *new_selected_add)  # 拆包 代替遍历
    # 如果存在取消勾选的商品
    if new_selected_rem:
        pl.srem('selected_%s' % user.id, *new_selected_rem)  # 拆包 代替遍历
    pl.execute()

    # 删除cookie
    response.delete_cookie('carts')  # 服了...
    return response


def get_cart_dict(cart_str):
    """将签名之后的购物车字符串数据转成明文字典"""

    # 将cart_str转成bytes类型的字符串 （签名str字符串 --> 签名bytes字符串）
    # encode：将str转成bytes（看得懂的转成看不懂的叫编码）
    # decode: 将bytes转成str
    cart_str_bytes = cart_str.encode()
    # 将cart_str_bytes转成bytes类型的字典 （签名bytes字符串 --> 签名bytes字典）
    cart_dict_bytes = base64.b64decode(cart_str_bytes)
    # 将cart_dict_bytes 转成真正的字典 （签名bytes字典 --> 明文str字典）
    cart_dict = pickle.loads(cart_dict_bytes)

    return cart_dict


def get_cart_str(cart_dict):
    """将明文字典转化成签名后的str"""

    # 将明文字典，转成bytes字典
    cart_dict_bytes = pickle.dumps(cart_dict)
    # 【签名】bytes字典（看得懂的转成看不懂的：编码）
    cart_str_bytes = base64.b64encode(cart_dict_bytes)
    # 将签名之后的b字典，转成 str字符串
    cart_str = cart_str_bytes.decode()

    return cart_str
